/*
 * Copyright 2020 eBlocker Open Source UG (haftungsbeschraenkt)
 *
 * Licensed under the EUPL, Version 1.2 or - as soon they will be
 * approved by the European Commission - subsequent versions of the EUPL
 * (the "License"); You may not use this work except in compliance with
 * the License. You may obtain a copy of the License at:
 *
 *   https://joinup.ec.europa.eu/page/eupl-text-11-12
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
package org.eblocker.lists.malware;

import org.eblocker.server.common.malware.MalwareEntry;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class MalwareEntries {
    private List<MalwareEntry> filteredUrls;
    private Map<String, Set<Integer>> filteredIpPorts;

    public MalwareEntries() {
        filteredUrls = new ArrayList<>();
        filteredIpPorts = new HashMap<>();
    }

    public MalwareEntries(List<MalwareEntry> filteredUrls, Map<String, Set<Integer>> filteredIpPorts) {
        this.filteredUrls = new ArrayList<>(filteredUrls);
        this.filteredIpPorts = new HashMap<>(filteredIpPorts);
    }

    public List<MalwareEntry> getFilteredUrls() {
        return filteredUrls;
    }

    public Map<String, Set<Integer>> getFilteredIpPorts() {
        return filteredIpPorts;
    }

    public void merge(MalwareEntries entries) {
        mergeFilteredUrls(entries.getFilteredUrls());
        mergeFilterIpPorts(entries.getFilteredIpPorts());
    }

    private void mergeFilteredUrls(List<MalwareEntry> filteredUrls) {
        Map<String, Set<String>> filteredUrlsByUrl = new HashMap<>();
        for(MalwareEntry e : this.filteredUrls) {
            filteredUrlsByUrl.put(e.getUrl(), new HashSet<>(Arrays.asList(e.getHostedMalware())));
        }

        for(MalwareEntry e : filteredUrls) {
            if (filteredUrlsByUrl.containsKey(e.getUrl())) {
                Set<String> hostedMalware = filteredUrlsByUrl.get(e.getUrl());
                hostedMalware.addAll(Arrays.asList(e.getHostedMalware()));
            } else {
                filteredUrlsByUrl.put(e.getUrl(), new HashSet<>(Arrays.asList(e.getHostedMalware())));
            }
        }

        this.filteredUrls = filteredUrlsByUrl.entrySet().stream().map(e -> new MalwareEntry(e.getKey(), e.getValue().toArray(new String[0]))).collect(Collectors.toList());
    }

    private void mergeFilterIpPorts(Map<String, Set<Integer>> filteredIpPorts) {
        for(Map.Entry<String, Set<Integer>> e : filteredIpPorts.entrySet()) {
            if (this.filteredIpPorts.containsKey(e.getKey())) {
                this.filteredIpPorts.get(e.getKey()).addAll(e.getValue());
            } else {
                this.filteredIpPorts.put(e.getKey(), new HashSet<>(e.getValue()));
            }
        }
    }
}
